// from https://atomgit.com/flow-step/SetupJava

import * as step from '@flow-step/step-toolkit'
import path from 'path';
import fs from "fs";

const ENV_NAME_JDK_VERSION: string = 'JDK_VERSION'
const ENV_NAME_MAVEN_VERSION: string = 'MAVEN_VERSION'
const ENV_NAME_JDK_INSTALL_PATH: string = 'INSTALL_JDK_PATH'
const ENV_NAME_MAVEN_INSTALL_PATH: string = 'INSTALL_MAVEN_PATH'

export async function setupJavaAndMaven(): Promise<void> {
    const inputJdkVersion: string | undefined =
        process.env[ENV_NAME_JDK_VERSION]
    const inputMavenVersion: string | undefined =
        process.env[ENV_NAME_MAVEN_VERSION]

    if (inputJdkVersion == undefined) {
        let errMsg = 'missing jdk version';
        throw new Error(errMsg)
    }

    if (inputMavenVersion == undefined) {
        let errMsg = 'missing maven version';
        throw new Error(errMsg)
    }


    const installJDKPath: string | undefined =
        process.env[ENV_NAME_JDK_INSTALL_PATH]
    const installMavenPath: string | undefined =
        process.env[ENV_NAME_MAVEN_INSTALL_PATH]
    await installJDK(inputJdkVersion, installJDKPath)
    await installMaven(inputMavenVersion, installMavenPath)

}

export async function installJDK(inputJdkVersion: string, installPath: string | undefined): Promise<void> {
    let toolName: string = 'jdk'
    let jdkVersion: string = mapJDKVersion(inputJdkVersion)
    if (jdkVersion === "") {
        throw new Error(`JDK version ${inputJdkVersion} not support now.`)
    }
    let platform: string = step.platform.getPlatform()
    //Windows/macos只支持下载安装jdk11及以上版本
    const unsupportedVersions = new Set(['6', '7', '8', '9', '10']);
    if ((platform === step.platform.PLATFORM_WIN || platform === step.platform.PLATFORM_DARWIN) && unsupportedVersions.has(jdkVersion)) {
        let errMsg = `Windows/macos does not support setup for JDK versions: ${[...unsupportedVersions].join('、')}`;
        throw new Error(errMsg)
    }
    step.info(`Going to install the jdk with version ${jdkVersion}`)

    let toolSuffix = getToolSuffix(platform)
    const jdkCachedPath = await step.tool.install(toolName, jdkVersion, toolSuffix)
    setupJava(jdkCachedPath)

    step.info(`Install Jdk ${jdkVersion} successfully!`)
    await symlinkInstallPathToCachePath(installPath, jdkCachedPath);
}

export async function symlinkInstallPathToCachePath(installPath: string | undefined, cachedPath: string) {
    if (installPath !== undefined) {
        fs.rmSync(installPath, {recursive: true, force: true})

        let msg = `Create link dir ${installPath} to ${cachedPath}`;
        try {
            fs.symlinkSync(cachedPath, installPath, 'dir')
            step.info(`${msg}`)
        } catch (err) {
            throw new Error(`${msg} failed, ${err}`)
        }
    }
}

export function setupJava(jdkPath: string): void {
    let javaHome: string = jdkPath
    let platform: string = step.platform.getPlatform()
    if (platform === step.platform.PLATFORM_DARWIN) {
        javaHome = path.join(javaHome, 'Contents/Home')
    }
    let javaBinPath = path.join(javaHome, 'bin')

    step.info(`JAVA_HOME: ${javaHome}`)
    step.exportEnvVar('JAVA_HOME', javaHome)

    step.info(`JavaBinPath: ${javaBinPath}`)
    step.addPath(javaBinPath)
}

export async function installMaven(inputMavenVersion: string, installPath: string | undefined): Promise<void> {
    let toolName: string = 'maven'
    step.info(`Going to install the maven with version ${inputMavenVersion}`)

    let platform: string = step.platform.getPlatform()
    let toolSuffix = getToolSuffix(platform)
    const mavenCachePath = await step.tool.install(toolName, inputMavenVersion, toolSuffix)
    setupMaven(mavenCachePath)

    step.info(`Install Maven ${inputMavenVersion} successfully`)
    await symlinkInstallPathToCachePath(installPath, mavenCachePath)
}

export function setupMaven(mavenCachePath: string): void {
    let mavenHome: string = mavenCachePath
    let mavenBinPath = path.join(mavenHome, 'bin')

    step.info(`MAVEN_HOME: ${mavenBinPath}`)
    step.exportEnvVar('MAVEN_HOME', mavenHome)

    step.info(`MavenBinPath: ${mavenBinPath}`)
    step.addPath(mavenBinPath)
}

export function getToolSuffix(platform: string): string {
    return platform === step.platform.PLATFORM_WIN ? "zip" : "tar.gz";
}

export function mapJDKVersion(jdkVersion: string): string {
    switch (jdkVersion) {
        case 'jdk1.6':
            return '6'
        case 'jdk1.7':
            return '7'
        case 'jdk1.8':
            return '8'
        case 'jdk1.9':
            return '9'
        case 'jdk10':
            return '10'
        case 'jdk11':
        case 'jdk11.0.13':
            return '11'
        case 'jdk17':
            return '17'
        case 'jdk18':
            return '18'
        case 'jdk19':
        case 'jdk19.0.1':
            return '19.0.1'
        case 'jdk20':
        case 'jdk20.0.2':
            return '20.0.2'
        case 'jdk21':
            return '21'
        default:
            return ""
    }
}